package com.sunday.gateway.mock.security.webflux.login.handler;

import com.sunday.common.core.enums.ErrorCodeEnum;
import com.sunday.common.core.remoting.rest.response.RestResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;


@Slf4j
public class JsonServerAuthenticationFailureHandler implements ServerAuthenticationFailureHandler {

    /**
     * 当验证尝试失败时调用
     */
    @Override
    public Mono<Void> onAuthenticationFailure(WebFilterExchange exchange, AuthenticationException exception) {
        log.info("登陆失败 {}", exception.toString());
        ServerHttpResponse response = exchange.getExchange().getResponse();
        if (exception instanceof UsernameNotFoundException) {
            //A0_201(ErrorClassifyEnum.A + "0201","用户账户不存在"),
            return writeErrorMessage(response, ErrorCodeEnum.A0_201);
        }
//        else if (exception instanceof UsernameOrPasswordException) {
//            //A0_221(ErrorClassifyEnum.A + "0221","账户或密码错误"),
//            return writeErrorMessage(response, ErrorCodeEnum.A0_221);
//        }
        else if (exception instanceof LockedException) {
            // A0_322(ErrorClassifyEnum.A + "0322","账号被冻结"),
            return writeErrorMessage(response, ErrorCodeEnum.A0_322);
        }
//        else if (exception instanceof CaptchaException) {
//            // A0_240(ErrorClassifyEnum.A + "0240","用户验证码错误"),
//            return writeErrorMessage(response, ErrorCodeEnum.A0_240);
//        }
        // A0_200(ErrorClassifyEnum.A + "0200","用户登录异常"),
        return writeErrorMessage(response, ErrorCodeEnum.A0_200);
    }

    private Mono<Void> writeErrorMessage(ServerHttpResponse response, ErrorCodeEnum errorCodeEnum) {

        RestResponse<String> restResponse = RestResponse.error(errorCodeEnum, RestResponse.ShowTypeEnum.SILENT);

        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        DataBufferFactory dataBufferFactory = response.bufferFactory();
        DataBuffer buffer = dataBufferFactory.wrap(restResponse.toJson().getBytes(Charset.defaultCharset()));
        return response.writeWith(Mono.just(buffer)).doOnError((_) -> DataBufferUtils.release(buffer));
    }

}